﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.RemoteCryptoRsaServiceProvider
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System;
using System.Security.Cryptography;

namespace Microsoft.InfoCards
{
  internal sealed class RemoteCryptoRsaServiceProvider : RSA, ICspAsymmetricAlgorithm
  {
    private object m_sync = new object();
    private const int CRYPT_OAEP = 64;
    private X509CertificateTokenFactoryCredential m_credential;
    private RpcCryptoContext m_context;
    private CspKeyContainerInfo m_cspInfo;
    private UIAgentRequest m_request;
    private bool m_disposed;

    public RemoteCryptoRsaServiceProvider(
      X509CertificateTokenFactoryCredential credential,
      UIAgentRequest request)
    {
      this.m_credential = credential;
      this.m_context = new RpcCryptoContext(this.m_credential.PortName, this.m_credential.ContextKey);
      this.m_cspInfo = new CspKeyContainerInfo(new CspParameters()
      {
        KeyContainerName = "RpcCrypto",
        ProviderName = "RpcCrypto",
        ProviderType = 0,
        KeyNumber = 1
      });
      this.m_request = request;
    }

    CspKeyContainerInfo ICspAsymmetricAlgorithm.CspKeyContainerInfo
    {
      get
      {
        return this.m_cspInfo;
      }
    }

    byte[] ICspAsymmetricAlgorithm.ExportCspBlob(
      bool includePrivateParameters)
    {
      ICspAsymmetricAlgorithm key = this.m_credential.Certificate.PublicKey.Key as ICspAsymmetricAlgorithm;
      if (key == null)
        throw InfoCardTrace.ThrowHelperError((Exception) new NotSupportedException());
      if (includePrivateParameters)
        throw InfoCardTrace.ThrowHelperError((Exception) new NotSupportedException());
      return key.ExportCspBlob(false);
    }

    void ICspAsymmetricAlgorithm.ImportCspBlob(byte[] rawData)
    {
      throw InfoCardTrace.ThrowHelperError((Exception) new NotSupportedException());
    }

    public override string KeyExchangeAlgorithm
    {
      get
      {
        if (this.m_credential != null && this.m_credential.Certificate != null && (this.m_credential.Certificate.PublicKey != null && this.m_credential.Certificate.PublicKey.Key != null))
          return this.m_credential.Certificate.PublicKey.Key.KeyExchangeAlgorithm;
        return (string) null;
      }
    }

    public override string SignatureAlgorithm
    {
      get
      {
        if (this.m_credential != null && this.m_credential.Certificate != null && (this.m_credential.Certificate.PublicKey != null && this.m_credential.Certificate.PublicKey.Key != null))
          return this.m_credential.Certificate.PublicKey.Key.SignatureAlgorithm;
        return (string) null;
      }
    }

    public override int KeySize
    {
      get
      {
        if (this.m_credential != null && this.m_credential.Certificate != null && (this.m_credential.Certificate.PublicKey != null && this.m_credential.Certificate.PublicKey.Key != null))
          return this.m_credential.Certificate.PublicKey.Key.KeySize;
        return 0;
      }
      set
      {
        throw InfoCardTrace.ThrowHelperError((Exception) new NotSupportedException());
      }
    }

    public override KeySizes[] LegalKeySizes
    {
      get
      {
        return new KeySizes[1]
        {
          new KeySizes(this.KeySize, this.KeySize, 0)
        };
      }
    }

    public byte[] SignHash(int hashAlg, byte[] hash)
    {
      this.ThrowIfRemoteProcessDied();
      RemoteCryptoSignHashRequest cryptoSignHashRequest = new RemoteCryptoSignHashRequest(this.GetContext(), hashAlg, 0, hash);
      cryptoSignHashRequest.Process();
      byte[] signature = cryptoSignHashRequest.GetSignature();
      this.ThrowIfRemoteProcessDied();
      return signature;
    }

    public override byte[] DecryptValue(byte[] rgb)
    {
      this.ThrowIfRemoteProcessDied();
      byte[] buffer = new byte[rgb.Length];
      Array.Copy((Array) rgb, 0, (Array) buffer, 0, rgb.Length);
      RemoteCryptoDecryptRequest cryptoDecryptRequest = new RemoteCryptoDecryptRequest(this.GetContext(), 0, true, buffer, 0, buffer.Length, 0, (byte[]) null);
      cryptoDecryptRequest.Process();
      byte[] numArray = new byte[cryptoDecryptRequest.Length];
      Array.Copy((Array) cryptoDecryptRequest.GetBuffer(), cryptoDecryptRequest.Index, (Array) numArray, 0, cryptoDecryptRequest.Length);
      this.ThrowIfRemoteProcessDied();
      return numArray;
    }

    public override byte[] EncryptValue(byte[] rgb)
    {
      return ((RSA) this.m_credential.Certificate.PublicKey.Key).EncryptValue(rgb);
    }

    public override RSAParameters ExportParameters(bool includePrivateParameters)
    {
      if (includePrivateParameters || this.m_credential.Certificate.PublicKey == null)
        throw InfoCardTrace.ThrowHelperError((Exception) new CryptographicException(SR.GetString("ServiceCanNotExportCertIdentityPrivateKey")));
      if (this.m_credential.Certificate.PublicKey.Key is RSA)
        return ((RSA) this.m_credential.Certificate.PublicKey.Key).ExportParameters(false);
      throw InfoCardTrace.ThrowHelperError((Exception) new CryptographicException(SR.GetString("ServiceCanNotExportCertIdentityPrivateKey")));
    }

    public override void ImportParameters(RSAParameters parameters)
    {
      throw InfoCardTrace.ThrowHelperError((Exception) new NotSupportedException());
    }

    protected override void Dispose(bool disposing)
    {
      if (this.m_disposed)
        return;
      lock (this.m_sync)
      {
        if (this.m_disposed)
          return;
        int num = disposing ? 1 : 0;
        ((IDisposable) this.m_context).Dispose();
        this.m_disposed = true;
      }
    }

    private RpcCryptoContext GetContext()
    {
      if (!this.m_context.IsOpen)
        this.m_context.Open();
      return this.m_context;
    }

    private void ThrowIfRemoteProcessDied()
    {
      if (!this.m_request.ParentRequest.UIAgentActive)
        throw InfoCardTrace.ThrowHelperError((Exception) new CryptographicException(SR.GetString("RemoteCryptoSessionUnavailable")));
    }
  }
}
